//
//  CantripWorldSettingsController.m
//  Cantrip
//
//  Created by James Callender on Sun May 05 2002.
//  Copyright (c) 2001 James Callender. All rights reserved.
//

#import "CantripWorldSettingsController.h"

@implementation CantripWorldSettingsController

+ (id)sharedInstance
{
    static CantripWorldSettingsController *controller;

    if (!controller) {
	controller = [[CantripWorldSettingsController alloc] init];
    }

    return controller;
}

- (id)init
{
    if (self = [super initWithWindowNibName:@"CantripWorldSettingsWindow"]) {
	mActiveWorld = nil;
	mActiveModule = nil;
    }

    return self;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [blankDocument release];
    [super dealloc];
}

- (void)close
{
    [[self window] orderOut:nil];
}

- (void)windowDidLoad
{
    [oSelectorView setDelegate:self];
    [[self window] setLevel:NSNormalWindowLevel];
    [[self window] setDelegate:self];
    
    blankDocument = [[NSDocumentController sharedDocumentController] makeUntitledDocumentOfType:@"cworld"];
    [blankDocument retain];
    
//  [self setShouldCloseDocument:NO];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mainWindowDidChange:) 
						 name:NSWindowDidBecomeMainNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidVanish:) 
						 name:NSWindowDidMiniaturizeNotification object:nil]; 
//  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillClose:) 
//						 name:NSWindowWillCloseNotification object:nil];
//  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowDidMove:) 
//						 name:NSWindowDidMoveNotification object:nil]; 
}

- (id <CantripSettingsModuleProtocol>)selectedModule
{
    return mActiveModule; 
}

- (NSArray *)settingsModules
{
    return [oSelectorView modules];
}

- (void)addSettingsModule:(NSObject<CantripSettingsModuleProtocol> *)mod
{
    int width = ([[oSelectorView modules] count] + 1) * Selector_IconWidth;
    [[oSelectorView modules] addObject:mod];
    [oSelectorView setFrameSize:NSMakeSize(width, [oSelectorView frame].size.height)];
    [oSelectorView setNeedsDisplay:YES];
}

- (void)changeModuleView:(NSObject<CantripSettingsModuleProtocol> *)mod
{
    NSRect newWindowFrame;
    NSSize viewSize, minWindowSize, maxWindowSize;
    int extra = [[self window] frame].size.height - [oMainView frame].size.height;
	
    if (!mod) return;

    @try {
	[mod updateForWorld:mActiveWorld];
    } @catch (id exception) {
	[[CantripAppController controller] log:@"Module '%@' threw exception: %@\n", [mod settingsDisplayName], exception];
	NSRunAlertPanel(NSLocalizedString(@"Error", none), 
			NSLocalizedString(@"PluginError", 
					  @"A message for when a plugin causes an error.  Should have one %@ argument."), 
			NSLocalizedString(@"OK", none), nil, nil,
			[mod settingsDisplayName]);
	//NSRunAlertPanel(@"Error", @"An error has occured with a plugin.  Please report it to the developer of the plugin:\n\n\"%@\"", @"OK", 
	//	nil, nil, [mod settingsDisplayName]);
    }

    viewSize = [mod size];
    if ([mod respondsToSelector:@selector(minSize)]) minWindowSize = [mod minSize];
    else minWindowSize = [mod size];
    if ([mod respondsToSelector:@selector(maxSize)]) maxWindowSize = [mod maxSize];
    else maxWindowSize = [mod size];
    
    newWindowFrame = [[self window] frame];
    newWindowFrame.size = viewSize;
    
    [oSpinner startAnimation:self];
    [[oMainView selectedTabViewItem] setView:oLoadingView];
    
    newWindowFrame.size.height += extra;
    newWindowFrame.origin.y -= (viewSize.height - [oMainView frame].size.height);
    
    minWindowSize.width = (minWindowSize.width > 280 ? minWindowSize.width : 280);
    minWindowSize.height += extra;
    
    maxWindowSize.width = (maxWindowSize.width > 280 ? maxWindowSize.width : 280);
    maxWindowSize.height += extra;
    
    [[self window] setFrame:newWindowFrame display:YES animate:[[NSUserDefaults standardUserDefaults] boolForKey:@"animateSettingsWindowResize"]];
    [[oSelectorView enclosingScrollView] scrollClipView:(NSClipView *)[oSelectorView superview]
	    toPoint:[(NSClipView*)[oSelectorView superview] constrainScrollPoint:NSMakePoint([[oSelectorView modules] indexOfObject:mod] * 80, 0)]];
    [[oSelectorView enclosingScrollView] reflectScrolledClipView:(NSClipView *)[oSelectorView superview]];
    
    [[self window] setMinSize:minWindowSize];
    [[self window] setMaxSize:maxWindowSize];
    if ([mod settingsView]) [[oMainView selectedTabViewItem] setView:[mod settingsView]];
    else [[oMainView selectedTabViewItem] setView:oNullView];
    [oSpinner stopAnimation:self];
    
    mActiveModule = mod;
}

- (void)windowDidMove:(NSNotification *)notification
{
    NSEnumerator *e;
    NSWindow *theWindow, *window;
    NSRect frame, myFrame;
    BOOL hDidChange = NO, vDidChange = NO;
    float gravity = 20;

    return;
    
    theWindow = [notification object];
    if ([self window] != theWindow) return;
    myFrame = [theWindow frame];
    e = [[NSApp windows] objectEnumerator];
    
    if ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) return;
    //if ([[NSApp currentEvent] type] == NSLeftMouseDragged) return;
        
    if ([theWindow parentWindow])  {
	[[theWindow parentWindow] removeChildWindow:theWindow];
    }
    
    while (window = [e nextObject]) {
	if (window != theWindow && [window isVisible]) {
	    frame = [window frame];
	    /* horizontal magnet */
	    if (!hDidChange) {
		if (fabs(NSMinX(frame) - NSMinX(myFrame)) <= gravity) {
		    myFrame.origin.x = frame.origin.x;
		    hDidChange = YES;
		} else if (fabs(NSMinX(frame) - NSMaxX(myFrame)) <= gravity) {
		    myFrame.origin.x += NSMinX(frame) - NSMaxX(myFrame);
		    hDidChange = YES;
		} if (fabs(NSMaxX(frame) - NSMinX(myFrame)) <= gravity) {
		    myFrame.origin.x = NSMaxX(frame);
		    hDidChange = YES;
		} if (!hDidChange && fabs(NSMaxX(frame) - NSMaxX(myFrame)) <= gravity) {
		    myFrame.origin.x += NSMaxX(frame) - NSMaxX(myFrame);
		    hDidChange = YES;
		}
	    }
	    
	    if (!vDidChange) {
		if (fabs(NSMinY(frame) - NSMinY(myFrame)) <= gravity) {
		    myFrame.origin.y = frame.origin.y;
		    vDidChange = YES;
		} else if (fabs(NSMinY(frame) - NSMaxY(myFrame)) <= gravity) {
		    myFrame.origin.y += NSMinY(frame) - NSMaxY(myFrame);
		    vDidChange = YES;
		} else if (fabs(NSMaxY(frame) - NSMinY(myFrame)) <= gravity) {
		    myFrame.origin.y = NSMaxY(frame);
		    vDidChange = YES;
		} else if (fabs(NSMaxY(frame) - NSMaxY(myFrame)) <= gravity) {
		    myFrame.origin.y += NSMaxY(frame) - NSMaxY(myFrame);
		    vDidChange = YES;
		}
	    }
	}
	if (vDidChange || hDidChange) [window addChildWindow:theWindow ordered:NSWindowBelow];
	if (vDidChange && hDidChange) break;
    }
    if (vDidChange || hDidChange) {
	[theWindow setFrame:myFrame display:YES];
    }
    else
    {
    	[[theWindow parentWindow] removeChildWindow:theWindow];
    }
	
    //else [theWindow setFrameOrigin:
    //	NSMakePoint([NSEvent mouseLocation].x + mouseRelative.x, 
    //			[NSEvent mouseLocation].y + mouseRelative.y)];

}

- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)aWindow
{
    return [mActiveWorld undoManager];
}

- (void)showWindow:(id)sender
{
    [self mainWindowDidChange:[NSNotification notificationWithName:NSWindowDidBecomeMainNotification object:[NSApp mainWindow]]];

    if ([oSelectorView selectedModule] == nil) {
	[oSelectorView selectModuleAtIndex:0];
	[self changeModuleView:[oSelectorView selectedModule]];
    }

    [super showWindow:sender];
}

- (NSString *)windowTitleForDocumentDisplayName:(NSString *)displayName
{ 
    return [NSString stringWithFormat:@"%@ : %@", NSLocalizedString(@"Settings", @"The word 'Settings'"),
	(mActiveWorld ? [mActiveWorld displayName] : @"(none)")];
}

/*NSDocument CFWindowRef WindowPtr NSWindow changeWindowsItem undoManager
 - (void)setRepresentedFilename:(NSString *)aString;
 - (void)setTitleWithRepresentedFilename:(NSString *)filename;
*/ 
//if ([mActiveWorld fileName]) [[self window] setRepresentedFilename:[mActiveWorld fileName]];
//else [[self window] setTitle:@"dude"];
//[self synchronizeWindowTitleWithDocumentName];
//if ([mActiveWorld fileName] == nil || mActiveWorld == nil) {
//[[self window] setRepresentedFilename:@"Untitled"];
// RemoveWindowProxy([[self window] windowRef]);  windowWillReturnUndoManager

- (void)updateForWindow:(NSWindow *)window
{
    if (window) {
	mActiveWorld = [[window windowController] document];
	//[self setDocument:mActiveWorld];
	if ([mActiveWorld fileName]) {
	    [[self window] setRepresentedFilename:[mActiveWorld fileName]];
	    [[self window] setTitle:
		[NSString stringWithFormat:@"%@ : %@", NSLocalizedString(@"Settings", @"The word 'Settings'"),
		    [mActiveWorld displayName]]];
	}
	else [self setDocument:blankDocument];
    } else {
	mActiveWorld = nil;
	[self setDocument:blankDocument];
    }
    [mActiveModule updateForWorld:mActiveWorld];
}

- (void)updateAllForClose:(id)document
{
    NSWindow *newWindow = [NSApp mainWindow];

    if (newWindow) {
	mActiveWorld = [[newWindow windowController] document];
	//[self setDocument:mActiveWorld];
	if ([mActiveWorld fileName]) {
	    [[self window] setRepresentedFilename:[mActiveWorld fileName]];
	    [[self window] setTitle:
		[NSString stringWithFormat:@"%@ : %@", NSLocalizedString(@"Settings", @"The word 'Settings'"),
		    [mActiveWorld displayName]]];
	}
	else [self setDocument:blankDocument];
    } else {
	mActiveWorld = nil;
	[self setDocument:blankDocument];
    }
    [[oSelectorView modules] makeObjectsPerformSelector:@selector(updateForWorld:) withObject:mActiveWorld];
}

- (void)windowDidVanish:(NSNotification *)notification
{
    [self updateForWindow:[NSApp mainWindow]];
}

- (void)mainWindowDidChange:(NSNotification *)notification
{
    NSWindow *window = [notification object];
    if (mActiveWorld == [[window windowController] document]) return;
    [self updateForWindow:window];
}

- (CantripWorldSettingsSelector *)selectorView
{
    return oSelectorView;
}

@end
